
import json
import redis
from utils.mqtt_utils import send_mqtt_message, publish_message_to_redis
from utils.custom_logger import CustomLogger
from settings import MQTT_TOPIC, REDIS_HOST, REDIS_PORT, REDIS_DB, MQTT_SEND_QUEUE

from db_utils.postgresql_connection import PostgreSQLConnection
from db_utils.repositories.video_resources_table import VideoResourcesTable
from db_utils.repositories.devices_table import DevicesTable


'''
设备接收端核心代码：
if message['type'] == 'test_message':# 测试消息
    
    self.logger.debug(f"线程 {threading.current_thread().name} 收到测试消息: {message}")

elif message['type'] == 'notification': # 通知消息

    self.logger.debug(f"线程 {threading.current_thread().name} 收到通知消息: {message}")

    notification_table_methods =NotificationTableMethods(db.conn, db.cursor) 
    # 保存通知消息到数据库
    notification_table_methods.insert_notification(title=message['data']['title'], content=message['data']['content'])

elif message['type'] == 'health_video': # 健康视频消息

    self.logger.debug(f"线程 {threading.current_thread().name} 收到健康视频消息: {message}")

    health_video_table_methods = HealthVideoTableMethods(db.conn, db.cursor)
    # 保存健康视频消息到数据库
    health_video_table_methods.insert_health_video(data_json=json.dumps(message['data']))

elif message['type'] == 'update_software': # 软件升级

    self.logger.debug(f"线程 {threading.current_thread().name} 收到软件升级消息: {message}")

    command = message['data']['command']

    # command 是一个shell命令，执行这个命令即可升级软件执行： git pull
    stat = os.system(command)

    # 是否执行成功
    if stat == 0:
        self.logger.info(f"线程 {threading.current_thread().name} 软件升级成功: {message}")
    else:
        self.logger.error(f"线程 {threading.current_thread().name} 软件升级失败: {message}")'''

# 推送任务到设备类
class PushDeviceTask:
    logger = CustomLogger(
        logger_name='mqtt_module', 
        log_file_path='./logs/push_device_task.log'
    ).get_logger()


    # 任务种类


    def __init__(self):

        self.redis_client = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB)


    def publish_message_to_redis(self, send_topic, message):
        '''
        :param send_topic: MQTT topic to publish message
        :param message: JSON message to be published : {"type": "test_message", "data": {"device_code": "1234567890", "message": "Hello, World!"}}
        :return: None
        '''

        # message = {"send_topic": send_topic, "send_data": message}
        self.redis_client.lpush(MQTT_SEND_QUEUE, json.dumps(message))


    def send_test_message_to_redis(self, device_code, device_type="ischemic_pre_trainer"): # 下发测试消息到，

        topic = f"{device_type}_{device_code}/sub" # 设备订阅主题

        message = {
            "send_topic": topic, 
            "send_data": {
                "type": "test_message", 
                "data": {"device_code": device_code, "message": "from data center test message"}
            }
        }

        self.redis_client.lpush(MQTT_SEND_QUEUE, json.dumps(message))

        self.logger.info(f"topic: {topic}: Sent test message ")

        return True, "下发成功"


    def send_notification_message_to_redis(self, device_code, title, content, device_type="ischemic_pre_trainer"): # 下发通知消息到
        '''
        :param topic: MQTT topic to publish message
        :param title: notification title
        :param content: notification content
        :return: None
        '''

        topic = f"{device_type}_{device_code}/sub" # 设备订阅主题

        message = {
            "send_topic": topic,
            "send_data": {
                "type": "notification",
                "data": {"title": title, "content": content}
            }
        }

        self.redis_client.lpush(MQTT_SEND_QUEUE, json.dumps(message))

        self.logger.info(f"topic: {topic}: Sent notification message : {title}, {content}")

        return True, "下发成功"


    def send_notification_message_to_redis_by_device_id(self, device_id, title, content, device_type="ischemic_pre_trainer"): # 下发通知消息到
        '''
        :param topic: MQTT topic to publish message
        :param title: notification title
        :param content: notification content
        :return: None
        '''

        with PostgreSQLConnection() as (conn, cursor):

            device_table_methods = DevicesTable(conn, cursor)

            # 获取设备信息
            device_info = device_table_methods.get_device_by_id(device_id)
            if not device_info:
                self.logger.error(f"设备{device_id}不存在")
                return False, "设备不存在"
            
            device_code = device_info['device_code']

        topic = f"{device_type}_{device_code}/sub" # 设备订阅主题

        message = {
            "send_topic": topic,
            "send_data": {
                "type": "notification",
                "data": {"title": title, "content": content}
            }
        }

        self.redis_client.lpush(MQTT_SEND_QUEUE, json.dumps(message))

        self.logger.info(f"topic: {topic}: Sent notification message : {title}, {content}")

        return True, "下发成功"

    def send_health_video_message_to_redis(self, device_code, data, device_type="ischemic_pre_trainer"): # 下发健康视频消息到
        '''
        :param topic: MQTT topic to publish message
        :param data: [ {"url": "https://vjs.zencdn.net/v/oceans.mp4", "desc": "群鸟在海上捕鱼", "bg_image": "static/test/video1.jpg"}, ...]
        :return: None
        '''

        topic = f"{device_type}_{device_code}/sub" # 设备订阅主题

        message = {
            "send_topic": topic,
            "send_data": {
                "type": "health_video",
                "data": data
            }
        }

        self.redis_client.lpush(MQTT_SEND_QUEUE, json.dumps(message))

        self.logger.info(f"topic: {topic}: Sent health video message : {data}")

        return True, "下发成功"


    def send_health_video_message_to_redis_by_id(self, device_id, video_resources_id, device_type="ischemic_pre_trainer"): # 下发健康视频消息到

        with PostgreSQLConnection() as (conn, cursor):

            device_table_methods = DevicesTable(conn, cursor)

            # 获取设备信息
            device_info = device_table_methods.get_device_by_id(device_id)
            if not device_info:
                self.logger.error(f"设备{device_id}不存在")
                return False, "设备不存在"
            
            device_code = device_info['device_code']

            # 获取视频资源信息
            video_resources_table_methods = VideoResourcesTable(conn, cursor)

            video_resources_info = video_resources_table_methods.get_video_resources_by_id(video_resources_id)
            if not video_resources_info:
                self.logger.error(f"视频资源{video_resources_id}不存在")
                return False, "视频资源不存在"
            

            self.logger.info(f"video_resources_info: {video_resources_info}")

            data_json = video_resources_info['data_json'] # 并不是json格式的字符串，而是python的字典格式

        self.send_health_video_message_to_redis(device_code, data_json, device_type)

        return True, "下发成功"

    def send_update_software_message_to_redis(self, device_code, command, device_type="ischemic_pre_trainer"): # 下发软件升级消息到
        '''
        :param topic: MQTT topic to publish message
        :param command: shell command to upgrade software： cd /home/pi/baina-iot-integrated-platform && git pull
        :return: None
        '''
        topic = f"{device_type}_{device_code}/sub" # 设备订阅主题

        message = {
            "send_topic": topic,
            "send_data": {
                "type": "update_software",
                "data": {"command": command}
            }
        }

        self.redis_client.lpush(MQTT_SEND_QUEUE, json.dumps(message))

        self.logger.info(f"topic: {topic}: Sent update software message : {command}")

        return True, "下发成功"

    def send_update_software_message_to_redis_by_id(self, device_id, command, device_type="ischemic_pre_trainer"): # 下发软件升级消息到
        '''
        :param topic: MQTT topic to publish message
        :param command: shell command to upgrade software： cd /home/pi/baina-iot-integrated-platform && git pull
        :return: None
        '''
        with PostgreSQLConnection() as (conn, cursor):

            device_table_methods = DevicesTable(conn, cursor)

            # 获取设备信息
            device_info = device_table_methods.get_device_by_id(device_id)
            if not device_info:
                self.logger.error(f"设备{device_id}不存在")
                return False, "设备不存在"
            print(device_info)
            device_code = device_info['device_code']

        self.send_update_software_message_to_redis(device_code, command, device_type)

        return True, "下发成功"


    # 公用方法
    def send_message_to_redis(self, device_code, message_type, message_data, device_type="ischemic_pre_trainer"): # 下发消息到设备 公用方法
        '''
        :param topic: MQTT topic to publish message
        :param message_type: message type
        :param message_data: message data
        :return: None
        '''

        topic = f"{device_type}_{device_code}/sub" # 设备订阅主题

        message = {
            "send_topic": topic,
            "send_data": {
                "type": message_type,
                "data": message_data
            }
        }

        self.redis_client.lpush(MQTT_SEND_QUEUE, json.dumps(message))

        self.logger.info(f"topic: {topic}: Sent message : {message_type}, {message_data}")

        return True, "下发成功"




    


        

if __name__ == '__main__':

    # Send a test message to MQTT

    print("Sending test message to MQTT by send_mqtt_message() function.")
    message_json = {"type": "test_message", "data": {"device_code": "1234567890", "message": "Hello, World!"}}
    send_mqtt_message(MQTT_TOPIC, json.dumps(message_json))

    print("Sent test message to MQTT by send_mqtt_message() function.")
    # Publish a test message to Redis
    message_json = {"type": "test_message", "data": {"device_code": "1234567890", "message": "send to redis"}}
    publish_message_to_redis(MQTT_TOPIC, json.dumps(message_json))